<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Cookies 一键登录 E2E 测试</title>
    <style>
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'PingFang SC', 'Microsoft YaHei', sans-serif; margin: 24px; color: #1a202c; }
        h1 { font-size: 20px; margin: 0 0 16px; }
        .card { border: 1px solid #e2e8f0; border-radius: 8px; padding: 16px; margin-bottom: 16px; }
        label { display: block; font-size: 12px; color: #4a5568; margin-bottom: 6px; }
        input[type="text"], textarea { width: 100%; box-sizing: border-box; padding: 10px 12px; border: 1px solid #cbd5e0; border-radius: 6px; outline: none; }
        textarea { min-height: 120px; resize: vertical; }
        .row { display: grid; grid-template-columns: 1fr; gap: 12px; }
        .btns { display: flex; gap: 10px; flex-wrap: wrap; }
        button { padding: 10px 14px; border: 1px solid #2b6cb0; background: #3182ce; color: #fff; border-radius: 6px; cursor: pointer; }
        button.secondary { border-color: #4a5568; background: #4a5568; }
        button.ghost { border-color: #cbd5e0; background: #fff; color: #2d3748; }
        button:disabled { opacity: .6; cursor: not-allowed; }
        .logs { background: #0b1021; color: #e2e8f0; padding: 12px; border-radius: 6px; min-height: 180px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace; font-size: 12px; overflow: auto; }
        .tip { font-size: 12px; color: #718096; }
        .ok { color: #68d391; }
        .warn { color: #f6e05e; }
        .err { color: #fc8181; }
        .mono { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace; }
    </style>
</head>
<body>
    <h1>Cookies 一键登录 E2E 测试</h1>

    <div class="card">
        <div class="row">
            <div>
                <label>目标地址（targetUrl）</label>
                <input id="targetUrl" type="text" placeholder="例如：https://nr.ele.me/ 或 https://melody.shop.ele.me/" value="https://melody.shop.ele.me/app" />
            </div>
            <div>
                <label>Cookies 串（按 name=value; name2=value2; ... 传入）</label>
                <textarea id="cookiesInput" placeholder="a=1; b=2; WMSTOKEN=xxx"></textarea>
            </div>
        </div>
        <div class="btns" style="margin-top:12px;">
            <button id="btnPing">检测插件连通性（ping）</button>
            <button id="btnLogin">一键植入并打开目标页</button>
            <button id="btnAuth">京东授权测试</button>
            <button id="btnAuthDoudian">抖店授权测试</button>
            <button id="btnAuthMeituanEcom">美团经营宝授权测试</button>
            <button id="btnAuthEleme">饿了么授权测试</button>
            <button class="ghost" id="btnClear">清空日志</button>
        </div>
        <div class="tip" style="margin-top:8px;">
            如使用 file:// 打开，请在扩展详情中启用“允许访问文件网址”，或使用本地 HTTP 服务打开此页。
        </div>
    </div>

    <div class="card">
        <div style="display:flex;align-items:center;gap:8px;">
            <div>运行日志</div>
            <div id="extId" class="tip mono"></div>
        </div>
        <div id="logs" class="logs"></div>
        <div class="tip" style="margin-top:6px;">
            打开目标页后，若需人工核验，请在新标签页控制台执行：<span class="mono">document.cookie</span>
        </div>
    </div>

    <!-- 检测元素：供内容脚本识别并回填扩展信息 -->
    <div id="yunlianfangzhou-detection" data-plugin-name="云链方舟插件" data-request-extension-id="true" style="display:none;"></div>

    <script>
        (function(){
            const logs = document.getElementById('logs');
            const extId = document.getElementById('extId');
            
            // 用于存储授权成功的回调
            let onAuthSuccessCallback = null;

            function ts() {
                const d = new Date();
                const p = (n)=> String(n).padStart(2,'0');
                return `${p(d.getHours())}:${p(d.getMinutes())}:${p(d.getSeconds())}.${String(d.getMilliseconds()).padStart(3,'0')}`;
            }
            function log(text, cls) {
                const el = document.createElement('div');
                if (cls) el.className = cls;
                el.textContent = `[${ts()}] ${text}`;
                logs.appendChild(el);
                logs.scrollTop = logs.scrollHeight;
            }
            function clearLogs(){ logs.textContent=''; }

            // 从检测元素读取扩展ID（content.js 会回填）
            function tryReadExtensionId() {
                const el = document.getElementById('yunlianfangzhou-detection');
                const id = el && el.getAttribute('data-extension-id');
                if (id) { extId.textContent = `ExtensionID: ${id}`; return true; }
                return false;
            }
            setTimeout(tryReadExtensionId, 300);
            setTimeout(tryReadExtensionId, 1000);

            // 监听授权相关事件
            window.addEventListener('message', (e) => {
                const data = e.data;
                if (!data || data.type !== 'FROM_EXTENSION') return;
                
                // 处理授权成功事件（无messageId）
                if (data.action === 'authSuccess') {
                    log(`授权成功: ${data.message}`, 'ok');
                    // 如果有待处理的回调，触发它
                    if (onAuthSuccessCallback) {
                        onAuthSuccessCallback({ success: true });
                        onAuthSuccessCallback = null;
                    }
                }
                // 处理授权取消事件
                else if (data.action === 'authCancelled') {
                    log(`授权已取消: ${data.message}`, 'warn');
                    // 取消回调
                    if (onAuthSuccessCallback) {
                        onAuthSuccessCallback({ success: false, error: data.message });
                        onAuthSuccessCallback = null;
                    }
                }
            });

            // 通用消息发送（postMessage -> content.js -> background.js）
            function callPlugin(action, payload, timeoutMs=8000) {
                return new Promise((resolve) => {
                    const messageId = 'mid_' + Math.random().toString(36).slice(2);
                    const timer = setTimeout(() => {
                        log(`等待响应超时（${action}, ${messageId}）`, 'warn');
                        resolve({ success:false, error:'timeout' });
                        window.removeEventListener('message', onMessage);
                    }, timeoutMs);

                    function onMessage(e){
                        const data = e.data;
                        if (!data || data.type !== 'FROM_EXTENSION') return;
                        if (data.messageId !== messageId) return;
                        clearTimeout(timer);
                        window.removeEventListener('message', onMessage);
                        resolve(data.response);
                    }
                    window.addEventListener('message', onMessage);

                    window.postMessage({
                        type: 'FROM_PAGE',
                        action,
                        messageId,
                        ...payload
                    }, '*');
                });
            }

            // 绑定 UI
            document.getElementById('btnPing').addEventListener('click', async () => {
                log('开始检测插件连通性（ping）...');
                const res = await callPlugin('ping', {});
                if (res && res.success) {
                    log(`插件可用：v${res.version} ${res.pluginName} - ${res.message}`, 'ok');
                } else {
                    log(`插件不可用：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });

            document.getElementById('btnLogin').addEventListener('click', async () => {
                const targetUrl = document.getElementById('targetUrl').value.trim();
                const cookies = document.getElementById('cookiesInput').value.trim();
                if (!targetUrl) { log('请填写 targetUrl', 'warn'); return; }
                if (!cookies) { log('请填写 Cookies 串', 'warn'); return; }

                log('发送一键登录请求（先设置 Cookies，后打开页面）...');
                const res = await callPlugin('setCookiesAndOpenUrl', { targetUrl, cookies }, 15000);
                if (res && res.success) {
                    log(`已打开目标页面（TabID=${res.tabId}）。若需人工核验，请在新标签页控制台执行 document.cookie`, 'ok');
                    if (res.verified) {
                        log(`尝试写入总数: ${res.verified.totalTried}`, 'tip');
                        const miss = res.verified.missing || [];
                        log(`缺失数量: ${miss.length}`, miss.length ? 'warn' : 'ok');
                        if (miss.length) {
                            log(`缺失列表: ${JSON.stringify(miss)}`, 'warn');
                        }
                    }
                    if (res.probe) {
                        log(`登录态探测：${res.probe.ok ? '已登录' : '未登录'} (code=${res.probe.code ?? 'null'})`, res.probe.ok ? 'ok' : 'warn');
                        if (!res.probe.ok) {
                            log(`探测说明：${res.probe.message}`, 'warn');
                            log('若显示未登录，通常是 token 与 acctId 失效/不匹配，或站点需要服务端重新签发易变会话。', 'tip');
                        }
                    }
                } else {
                    log(`一键登录失败：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });
            
            document.getElementById('btnAuth').addEventListener('click', async () => {
                log('开始京东授权测试...');
                
                // 创建Promise用于等待授权成功
                const authPromise = new Promise((resolve) => {
                    onAuthSuccessCallback = resolve;
                    // 3分钟超时
                    setTimeout(() => {
                        if (onAuthSuccessCallback === resolve) {
                            onAuthSuccessCallback = null;
                            resolve({ success: false, error: '超时：请在新标签页中完成登录' });
                        }
                    }, 180000);
                });
                
                // 触发登录流程
                const res = await callPlugin('clearAndWaitForCookies', {
                    loginUrl: 'https://store.jddj.com/base/login',
                    cookieDomain: 'store.jddj.com',
                    loginKeyword: 'store_session'
                }, 5000); // 只需要等待消息发送成功，不需要等待登录完成
                
                if (res && res.success) {
                    log('已打开京东登录页面，请在弹窗中完成登录...', 'tip');
                    log('等待登录成功...', 'tip');
                    
                    // 等待授权成功（通过事件监听）
                    const authRes = await authPromise;
                    
                    if (authRes && authRes.success) {
                        log('登录成功！开始获取存储的Cookies...', 'ok');
                        
                        // 获取存储的cookies
                        const cookiesRes = await callPlugin('getStoredCookies', {}, 5000);
                        if (cookiesRes && cookiesRes.success && cookiesRes.cookies) {
                            const cookieCount = cookiesRes.cookies.split(';').length;
                            log(`成功获取Cookies，共 ${cookieCount} 项`, 'ok');
                            
                            // 检查关键字段
                            const cookies = cookiesRes.cookies;
                            const checks = {
                                'store_session': cookies.includes('store_session'),
                                'sdtoken': cookies.includes('sdtoken')
                            };
                            
                            log('关键Cookie检查：', 'tip');
                            for (const [key, exists] of Object.entries(checks)) {
                                log(`  ${key}: ${exists ? '✓' : '✗'}`, exists ? 'ok' : 'warn');
                            }
                            
                            // 显示cookies内容
                            document.getElementById('cookiesInput').value = cookies;
                            log('Cookies已自动填入上方文本区域', 'tip');
                        } else {
                            log('获取Cookies失败', 'err');
                        }
                    } else {
                        log(`授权测试失败：${authRes && authRes.error ? authRes.error : '未知错误'}`, 'err');
                    }
                } else {
                    log(`发起授权失败：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });

            document.getElementById('btnClear').addEventListener('click', clearLogs);
            
            document.getElementById('btnAuthDoudian').addEventListener('click', async () => {
                log('开始抖店授权测试...');
                
                // 创建Promise用于等待授权成功
                const authPromise = new Promise((resolve) => {
                    onAuthSuccessCallback = resolve;
                    // 3分钟超时
                    setTimeout(() => {
                        if (onAuthSuccessCallback === resolve) {
                            onAuthSuccessCallback = null;
                            resolve({ success: false, error: '超时：请在新标签页中完成登录' });
                        }
                    }, 180000);
                });
                
                // 触发登录流程
                const res = await callPlugin('clearAndWaitForCookies', {
                    loginUrl: 'https://fxg.jinritemai.com/login/common',
                    cookieDomain: 'fxg.jinritemai.com',
                    loginKeyword: 'csrf_session_id'
                }, 5000); // 只需要等待消息发送成功，不需要等待登录完成
                
                if (res && res.success) {
                    log('已打开抖店登录页面，请在弹窗中完成登录...', 'tip');
                    log('等待登录成功...', 'tip');
                    
                    // 等待授权成功（通过事件监听）
                    const authRes = await authPromise;
                    
                    if (authRes && authRes.success) {
                        log('登录成功！开始获取存储的Cookies...', 'ok');
                        
                        // 获取存储的cookies
                        const cookiesRes = await callPlugin('getStoredCookies', {}, 5000);
                        if (cookiesRes && cookiesRes.success && cookiesRes.cookies) {
                            const cookieCount = cookiesRes.cookies.split(';').length;
                            log(`成功获取Cookies，共 ${cookieCount} 项`, 'ok');
                            
                            // 检查关键字段
                            const cookies = cookiesRes.cookies;
                            const checks = {
                                'passport_csrf_token': cookies.includes('passport_csrf_token'),
                                'csrf_session_id': cookies.includes('csrf_session_id'),
                                'HMACCOUNT': cookies.includes('HMACCOUNT')
                            };
                            
                            log('关键Cookie检查：', 'tip');
                            for (const [key, exists] of Object.entries(checks)) {
                                log(`  ${key}: ${exists ? '✓' : '✗'}`, exists ? 'ok' : 'warn');
                            }
                            
                            // 显示cookies内容
                            document.getElementById('cookiesInput').value = cookies;
                            log('Cookies已自动填入上方文本区域', 'tip');
                        } else {
                            log('获取Cookies失败', 'err');
                        }
                    } else {
                        log(`授权测试失败：${authRes && authRes.error ? authRes.error : '未知错误'}`, 'err');
                    }
                } else {
                    log(`发起授权失败：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });
            
            document.getElementById('btnAuthMeituanEcom').addEventListener('click', async () => {
                log('开始美团经营宝授权测试...');
                
                // 创建Promise用于等待授权成功
                const authPromise = new Promise((resolve) => {
                    onAuthSuccessCallback = resolve;
                    // 3分钟超时
                    setTimeout(() => {
                        if (onAuthSuccessCallback === resolve) {
                            onAuthSuccessCallback = null;
                            resolve({ success: false, error: '超时：请在新标签页中完成登录' });
                        }
                    }, 180000);
                });
                
                // 触发登录流程
                const res = await callPlugin('clearAndWaitForCookies', {
                    loginUrl: 'https://ecom.meituan.com/',
                    cookieDomain: 'ecom.meituan.com',
                    loginKeyword: 'EBDFPID'
                }, 5000); // 只需要等待消息发送成功，不需要等待登录完成
                
                if (res && res.success) {
                    log('已打开美团经营宝登录页面，请在弹窗中完成登录...', 'tip');
                    log('等待登录成功...', 'tip');
                    
                    // 等待授权成功（通过事件监听）
                    const authRes = await authPromise;
                    
                    if (authRes && authRes.success) {
                        log('登录成功！开始获取存储的Cookies...', 'ok');
                        
                        // 获取存储的cookies
                        const cookiesRes = await callPlugin('getStoredCookies', {}, 5000);
                        if (cookiesRes && cookiesRes.success && cookiesRes.cookies) {
                            const cookieCount = cookiesRes.cookies.split(';').length;
                            log(`成功获取Cookies，共 ${cookieCount} 项`, 'ok');
                            
                            // 检查关键字段
                            const cookies = cookiesRes.cookies;
                            const checks = {
                                'EBDFPID': cookies.includes('EBDFPID'),
                                'bizType=1': cookies.includes('bizType=1') || /bizType\s*=\s*1/.test(cookies),
                                'logan_session_token': cookies.includes('logan_session_token')
                            };
                            
                            log('关键Cookie检查：', 'tip');
                            for (const [key, exists] of Object.entries(checks)) {
                                log(`  ${key}: ${exists ? '✓' : '✗'}`, exists ? 'ok' : 'warn');
                            }
                            
                            // 显示cookies内容
                            document.getElementById('cookiesInput').value = cookies;
                            log('Cookies已自动填入上方文本区域', 'tip');
                        } else {
                            log('获取Cookies失败', 'err');
                        }
                    } else {
                        log(`授权测试失败：${authRes && authRes.error ? authRes.error : '未知错误'}`, 'err');
                    }
                } else {
                    log(`发起授权失败：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });
            
            document.getElementById('btnAuthEleme').addEventListener('click', async () => {
                log('开始饿了么授权测试...');
                
                // 创建Promise用于等待授权成功
                const authPromise = new Promise((resolve) => {
                    onAuthSuccessCallback = resolve;
                    // 3分钟超时
                    setTimeout(() => {
                        if (onAuthSuccessCallback === resolve) {
                            onAuthSuccessCallback = null;
                            resolve({ success: false, error: '超时：请在新标签页中完成登录' });
                        }
                    }, 180000);
                });
                
                // 触发登录流程
                // 饿了么商家后台登录地址是 melody.shop.ele.me/login，登录关键字是 ksid 或 shopId
                const res = await callPlugin('clearAndWaitForCookies', {
                    loginUrl: 'https://melody.shop.ele.me/login',
                    cookieDomain: 'melody.shop.ele.me',
                    loginKeyword: 'ksid'
                }, 5000); // 只需要等待消息发送成功，不需要等待登录完成
                
                if (res && res.success) {
                    log('已打开饿了么登录页面，请在弹窗中完成登录...', 'tip');
                    log('等待登录成功...', 'tip');
                    
                    // 等待授权成功（通过事件监听）
                    const authRes = await authPromise;
                    
                    if (authRes && authRes.success) {
                        log('登录成功！开始获取存储的Cookies...', 'ok');
                        
                        // 获取存储的cookies
                        const cookiesRes = await callPlugin('getStoredCookies', {}, 5000);
                        if (cookiesRes && cookiesRes.success && cookiesRes.cookies) {
                            const cookieCount = cookiesRes.cookies.split(';').length;
                            log(`成功获取Cookies，共 ${cookieCount} 项`, 'ok');
                            
                            // 检查关键字段
                            const cookies = cookiesRes.cookies;
                            const checks = {
                                'ksid': cookies.includes('ksid'),
                                'shopId': cookies.includes('shopId'),
                                'SID': cookies.includes('SID')
                            };
                            
                            log('关键Cookie检查：', 'tip');
                            for (const [key, exists] of Object.entries(checks)) {
                                log(`  ${key}: ${exists ? '✓' : '✗'}`, exists ? 'ok' : 'warn');
                            }
                            
                            // 显示cookies内容
                            document.getElementById('cookiesInput').value = cookies;
                            log('Cookies已自动填入上方文本区域', 'tip');
                        } else {
                            log('获取Cookies失败', 'err');
                        }
                    } else {
                        log(`授权测试失败：${authRes && authRes.error ? authRes.error : '未知错误'}`, 'err');
                    }
                } else {
                    log(`发起授权失败：${res && res.error ? res.error : '未知错误'}`, 'err');
                }
            });
        })();
    </script>
</body>
</html>


